## 14.3. CVS Administrator Reference

This section provides details on creating and configuring repositories and performing other CVS administrative tasks. A single computer can run multiple copies of the CVS server, and each server can serve multiple repositories.

### 14.3.1. Creating a Repository

Select a directory that will contain the repository files (/usr/local/cvsrep is used in the following examples). Use the init command to initialize the repository. Either set the `$CVSROOT` environment variable first:

>     user@localhost$ export CVSROOT=/usr/local/cvsrep
>     user@localhost$ cvs init

or use the -d option to specify the repository location:

>     user@localhost$ cvs -d /usr/local/cvsrep init

For information on importing code, see Section 14.4, "CVS User Reference", especially Section 14.4.7.11, "import" and Section 14.4.7.1, "add" sections.

### 14.3.1.1. Setting up the password server

If you want users to access the repository from other computers, then configure the `pserver` by doing the following as root:

- Make sure there is an entry in /etc/services similar to the following:

  >     cvspserver 2401/tcp

- If you are not using `tcpwrappers`, then place a line like this in /etc/inetd.conf:

  >     cvspserver stream tcp nowait root /usr/bin/cvs cvs
  >     --allow-root=/usr/local/cvsroot pserver

- Or, if you are using `tcpwrappers`, then use a line like this:

  >     cvspserver stream tcp nowait root /usr/sbin/tcpd /usr/bin/cvs
  >     --allow-root=/usr/local/cvsroot pserver

- Once these changes are in place, restart inetd (or send it the appropriate signal to cause it to re-read inetd.conf).

### 14.3.2. Security Issues

The following are security issues that need to be considered when working with CVS:

- The contents of files will be transmitted in the open over the network with `pserver` and rsh. With `pserver`, passwords are transmitted in the open as well.

- When using a local repository (i.e., when CVS is not being used in client/server mode), developers need write access to the repository, which means they can hack it.

- The CVS server runs as root briefly before changing its user ID.

- The ~/.cvspass file must be kept unreadable by all users except the owner to prevent passwords from being accessible.

- A user who has authority to make changes to the files in the CVSROOT module can run arbitrary programs.

- Some of the options to the admin command are very dangerous, so it is advisable to restrict its use. This can be accomplished by creating a user group named `cvsadmin`. If this user group exists, then only users in that group can run the admin command (except admin -k kflag, which is available to everyone).

### 14.3.3. Repository Structure

The CVS repository is implemented as a normal directory with special contents. This section describes the contents of the repository directory.

### 14.3.3.1. The CVSROOT directory

The CVSROOT directory contains the administrative files for the repository; other directories in the repository contain the modules. The administrative files permit (and ignore) blank lines and comment lines in addition to the lines with real configuration information on them. Comment lines start with a hash mark (``#`').

Some of the administrative files contain filename patterns to match file and directory names. These patterns are regular expressions like those used in GNU Emacs. Table 14-2 contains the special constructions used most often.

#### Table 14-2. Filename Pattern Special Constructions

Construction | Description
--- | ---
`^` | Match the beginning of the string.
`$` | Match the end of the string.
`.` | Match any single character.
`*` | Modify the preceding construct to match zero or more repetitions.

CVS will perform a few important expansions in the contents of the administrative files before interpreting the results. First, the typical shell syntax for referring to a home directory is `~/`, which expands to the home directory of the user running CVS; and `~`user expands to the home directory of the specified user.

In addition, CVS provides a mechanism similar to the shell's environment variable expansion capability. Constructs such as `${`variable`}` will be replaced by the value of the named variable. Variable names start with letters and consist entirely of letters, numbers, and underscores. Curly brackets may be omitted if the character immediately following the variable reference is not a valid variable name character. While this construct looks like a shell environment variable reference, the full environment is not available. Table 14-3 contains the built-in variables.

#### Table 14-3. Administrative File Variables

Variable | Description
--- | ---
CVSEDITOR EDITOR VISUAL | The editor CVS uses for log file editing.
CVSROOT | The repository locator in use.
USER | The name of the user (on the server, if using a remote repository) running CVS.
=var | The value of a user-defined variable named var. Values for these variables are provided by the global -s option.

In order to edit these files, check out the CVSROOT module from the repository, edit the files, and commit them back to the repository. You must commit the changes for them to affect CVS's behavior.

Table 14-4 describes the administrative files and their functions.

#### Table 14-4. CVSROOT Files

File | Description
--- | ---
checkoutlist | Extra files to be maintained in CVSROOT
commitinfo | Specifications for commit governors
config | Settings to affect the behavior of CVS
cvsignore | Filename patterns of files to ignore
cvswrappers | Specifications for checkout and commit filters
editinfo | Specifications for log editors (obsolete)
history | Log information for the history command
loginfo | Specify commit notifier program(s)
modules | Module definitions
notify | Notification processing specifications
passwd | A list of users and their CVS-specific passwords
rcsinfo | Template form for log messages
readers | A list of users having read-only access
taginfo | Tag processing specifications
users | Alternate user email addresses for use with notify
verifymsg | Specify log message evaluator program
writers | A list of users having read/write access

Since the editinfo file is obsolete, use the `$EDITOR` environment variable (or the -e option) to specify the editor and the verifymsg file to specify an evaluator.

Each line of the taginfo file contains a filename pattern and a command line to execute when files with matching names are tagged.

### 14.3.3.2. The checkoutlist file

Whenever changes to files in the CVSROOT module are committed, CVS prints the message:

>     cvs commit: Rebuilding administrative file database

to inform you that the checked-out copy in the repository has been updated to reflect any changes just committed. As with any other module directory in the repository, the CVSROOT directory contains RCS (*,v) files that retain the history of the files. But to use the files, CVS needs a copy of the latest revision. So, when CVS prints this message, it is checking out the latest revisions of the administrative files.

If you have added files to the CVSROOT module (such as scripts to be called via entries in the loginfo file), you will need to list them in the checkoutlist file. This makes CVS treat them the same way as it treats the standard set of CVSROOT files.

Each line in this file consists of a filename and an optional error message that is displayed in case there is trouble checking out the file.

### 14.3.3.3. The commitinfo file

Whenever a commit is being processed, CVS consults this file to determine whether or not any precommit checking of the file is required. Each line of the file contains a directory name pattern, followed by the path of a program to invoke when files are commited in directories with matching names.

Aside from the usual filename-pattern syntax, there are two special patterns:

`ALL`

  If this pattern is present in the file, then all files are passed to the specified checking program. CVS then looks for a pattern that matches the name of each particular file and runs the additional checks found, if any.

`DEFAULT`

  If this pattern is present in the file, all files for which there was no pattern match are sent to the specified checking program. The automatic match of every file to the `ALL` entry, if any, does not count as a match when determining whether or not to send the file to the `DEFAULT` checking program.

CVS constructs the command line for the checking program by appending the full path to the directory within the repository and the list of files being committed (this means you can specify the first few command-line arguments to the program, if necessary). If the checking program exits with a nonzero status, the commit is aborted.

The programs that run via this mechanism run on the server computer when a remote repository is used. Here is an example of a commitinfo file:

>     ALL $CVSROOT/CVSROOT/commit-ALL.pl
>     DEFAULT $CVSROOT/CVSROOT/commit-DEFAULT.pl
>     CVSROOT$ $CVSROOT/CVSROOT/commit-CVSROOT.pl

This example assumes you will create the script files in the CVSROOT module and add them to the checkoutlist file.

### 14.3.3.4. The config file

Repository configuration is specified in the config administrative file.

`LockDir=`dir

  Directs CVS to put its lock files in the alternate directory given instead of in the repository itself, allowing users without write access to the repository (but with write access to dir) to read from the repository.

  Version 1.10 doesn't support alternate directories for lock files and reports an error if this option is set. Older versions of CVS (1.9 and older) don't support this option either and will not report an error. Do not mix versions that support alternate directories for lock files with versions that don't, since lock files in both places defeat the purpose of having them.

`RCSBIN=`dir

  Obsolete (used in versions 1.9.12 to 1.9.18). This option used to tell CVS where to find RCS programs. Since all RCS-related functions are now handled internally, this option does nothing.

`SystemAuth=`value

  CVS tries to authenticate users via the CVSROOT/passwd file first, and if that fails and this option is set to `yes`, CVS tries to authenticate via the system's user database. This option is used with the password server. The default is `yes`.

`TopLevelAdmin=`value

  If this option is set to `yes`, an additional CVS directory is created at the top-level directory when checkout is run. This allows the client software to detect the repository locator in that directory (see Section 14.4.1, "Repository Locators"). The default is `no`.

  This option is useful if you check out multiple modules to the same sandbox directory. If it is enabled, you won't have to provide a repository locator after the first checkout; CVS infers it from the information in the top-level CVS directory created during the first checkout.

### 14.3.3.5. The cvsignore file

The cvsignore administrative file contains a list of filename patterns to ignore, just like the .cvsignore files that can appear in sandboxes and user home directories. Unlike the filename patterns in other administrative files, these patterns are in sh syntax; they are not GNU Emacs-style regular expressions. There can be multiple patterns on a line, separated by whitespace (consequently, the patterns themselves cannot contain whitespace).

Table 14-5 shows the most commonly used sh-style pattern constructs.

#### Table 14-5. Filename Patterns for cvsignore

Construct | Description
--- | ---
`?` | Any one character.
`*` | Any sequence of zero or more characters.

Again, diverging from the standards used by the rest of the administrative files, the cvsignore file does not support comments.

### 14.3.3.6. The cvswrappers file

While the cvsignore file allows CVS to ignore certain files, the cvswrappers file allows you to give CVS default options for commands that work with files. Lines in this file consist of a sh-style filename pattern followed by a -k (keyword substitution mode) option and/or an -m (update method) option. The legal values for -k are described in Table 14-19. The legal values for -m are `COPY` and `MERGE`.

If -m COPY is specified, CVS will not attempt to merge the files. Instead, it presents the user with conflicting versions of the file, and he can choose one or the other or resolve the conflict manually.

For example, to treat all files ending in .exe as binary, add this line to the file:

>     *.exe -k b

### 14.3.3.7. The history file

If this file exists, CVS inserts records of activity against the repository. This information produces displays of the cvs history command. The history file is not intended for direct reading or writing by programs other than CVS.

A repository set up with cvs init automatically has a history file.

### 14.3.3.8. The loginfo file

The loginfo administrative file works much like the commitinfo file and can use the special patterns `ALL` and `DEFAULT`. This file allows you to do something with commit log messages and related information.

The programs called during loginfo processing receive the log message on standard input. Table 14-6 shows the three codes that can pass additional information to the called programs via command-line arguments.

#### Table 14-6. Special loginfo Variables

Variable | Description
--- | ---
`s` | Filename
`V` | Pre-commit revision number
`v` | Post-commit revision number

If a percent sign (`%`) followed by the desired variable is placed after the command path, CVS inserts the corresponding information as a whitespace-separated list with one entry for each file, preceded by the repository path (as with commitinfo). There can be only one percent sign on the command line, so if you want information from more than one variable, place the variable names inside curly brackets: `%{...}`. In this case, each file-specific entry has one field for each variable, separated by commas. For example, the code `%{sVv}` expands into a list like this:

>     /usr/local/cvsrep/hello Makefile,1.1,1.2 hello.c,1.8,1.9

It can be helpful to send email notifications each time someone commits a file to the repository. Developers can monitor this stream of notices to determine when they should pull the latest development code into their private sandboxes. For example, consider a developer doing some preparatory work in his sandbox while he awaits stabilization and addition of another developer's new library. As soon as the new library is added and committed, email notification goes out, and the waiting developer sees the code is ready to use. So, he runs cvs upd -d in the appropriate directory to pull in the new library code and then sets about integrating it with his work.

It is simple to set up this kind of notification. Just add a line like this to the CVSROOT/loginfo file:

>     DEFAULT mail -s %s developers@company.com

Often, the email address is a mailing list, which has all the interested parties (developers or otherwise) on the distribution list. If you want to send messages to multiple email addresses, you can write a script to do that and have that script called via this file. Alternatively, you can use the log.pl program that comes as part of the CVS source distribution (located at /usr/local/src/cvs-1.10.8/contrib/log.pl, assuming CVS was unpacked into /usr/local/src). Instructions for its use are provided as comments in the file.

### 14.3.3.9. The modules file

The top-level directories in a repository are called modules. In addition to these physical modules, CVS provides a mechanism to create logical modules through the modules administrative file. Here are the three kinds of logical modules:

Alias

  Alias modules are defined by lines of the form:

  >     module_name -a alias_module ...

  You can use the alias module name in CVS commands in the same way you use the modules named after the -a option.

Regular

  Regular modules are defined by lines of the form:

  >     module_name [options] directory file ...

  Checking out module_name results in the specified files from directory being checked out into a directory named module_name. The intervening directories (if any) are not reflected in the sandbox.

Ampersand

  Ampersand modules are defined by lines of the form:

  >     module_name [options] &other_module ...

  Checking out such a module results in a directory named module_name, which in turn contains copies of the other_module modules.

Table 14-7 shows the options that can define modules.

#### Table 14-7. Module Options

Option | Description
--- | ---
-d name | Overrides the default working directory name for the module
-e prog | Runs the program prog when files are exported from the module; the module name is passed to prog as the sole argument
-i prog | Runs the program prog when files are committed to the module; the repository directory of the committed files is passed in to prog as the sole argument
-i prog | Runs the program prog when files are checked out from the module; the module name is passed in to prog as the sole argument
-s status | Assigns a status descriptor to the module
-t prog | Runs the program prog when files are tagged in the module using rtag; the module name and the symbolic tag are passed to prog
-u prog | Runs the program prog when files are updated in the module's top-level directory; the full path to the module within the repository is passed to prog as the sole argument

Alias modules provide alternative names for other modules or shortcuts for referring to collections or subdirectories of other modules. Alias module definitions function like macro definitions in that they cause commands to run as if the expanded list of modules and directories was on the command line. Alias modules do not cause the modules of their definition to be grouped together under the alias name (use ampersand modules for that). For example, the definition:

>     h -a hello

makes the name h a synonym for the hello module. This definition:

>     project -a library client server

allows you to check out all three modules of the project as a unit. If an entry in the definition of an alias module is preceded by an exclamation point (`!`), then the named directory is excluded from the module.

Regular modules allow you to create modules that are subsets of other modules. For example, the definition:

>     header library library.h

creates a module that just contains the header file from the library module.

Ampersand modules are true logical modules. There are no top-level directories for them in the repository, but you can check them out to sandboxes, and directories with their names will then appear. The modules listed in the definition are below that directory. For example:

>     project &library &client &server

is almost the same as the alias module example given earlier, except that the submodules are checked out inside a subdirectory named project.

In this file, long definitions may be split across multiple lines by terminating all but the last line with backslashes (`\`).

### 14.3.3.10. The notify file

This file is used in conjunction with the watch command. When notifications are appropriate, this file is consulted to determine how to do the notification.

Each line of the notify file contains a filename pattern and a command line. CVS's notification mechanism uses the command line specified to perform notifications for files having names that match the corresponding pattern.

There is a single special-purpose variable, `%s`, that can appear in the command specification. When the command is executed, the name of the user to notify replaces the variable name. If the users administrative file exists, the user names are looked up there, and the resulting values are used for `%s` instead. This allows emails to be sent to accounts other than those on the local machine. Details are sent to the notification program via standard input.

Typical usage of this feature is the single entry:

>     ALL mail %s -s "CVS notification"

In fact, this entry is present in the default notify file created when you run cvs init to create a repository (although it is initially commented out).

### 14.3.3.11. The passwd file

If you access the repository via a pserver repository locator (see Section 14.4.1, "Repository Locators"), then CVS can have its own private authentication information, separate from the system's user database. This information is stored in the CVSROOT/passwd administrative file.

This feature provides anonymous CVS access over the Internet. By creating an entry for a public user (usually anoncvs or anonymous), the pserver can be used by many people sharing the public account. If you don't want to create a system user with the same name as the public user, or if you have such a user but it has a different purpose, you can employ a user alias to map it to something else:

>     anonymous:TY7QWpLw8bvus:cvsnoname

Then, make sure you create the `cvsnoname` user on the system. You can use /bin/false as the login shell and the repository's root directory as the home directory for the user.

To restrict the public user to read-only access, list it in the CVSROOT/readers administrative file.

Additionally, CVS's private user database is useful even if you don't want to set up anonymous CVS access. You can restrict access to a subset of the system's users, provide remote access to users who don't have general system access, or prevent a user's normal system password from being transmitted in the clear over the network (see Section 14.3.2, "Security Issues").

There is no cvs passwd command for setting CVS-specific passwords (located in the repository file CVSROOT/passwd). CVS-specific user and password management are manual tasks.

### 14.3.3.12. The rcsinfo file

CVS consults this file when doing a commit or import to determine the log message editor template. Each entry in the file consists of a filename pattern and the name of the file to use as the template for module directories with matching names.

The `ALL` and `DEFAULT` special patterns apply to this file.

### 14.3.3.13. The readers file

If this file exists, users listed in it have read-only access.

### 14.3.3.14. The taginfo file

CVS consults this file whenever the tag or rtag commands are used. Entries in this file are filename patterns and program specifications. The `ALL` special pattern applies to this file.

The taginfo file is called with the tag, the operation being performed, the module directory name (relative to the repository root), and the filename and revision number for each affected file. The valid operations are: `add` (for tag), `del` (for tag -d), and `mov` (for tag -F).

If the taginfo program returns a nonzero status, the tag or rtag command that caused its execution is aborted.

### 14.3.3.15. The users file

If this file exists, it is consulted during processing of the notify administrative file's contents. Entries in this file consist of two colon-separated fields on a single line. The first field is the name of a user, and the second field is a value (normally the user's email address on another machine). For example:

>     john:john@somecompany.com
>     jane:jane@anothercompany.com

### 14.3.3.16. The verifymsg file

CVS consults this file to determine if log messages should be validated. If the program returns a nonzero status, the commit is aborted. The verifymsg file is called with the full path to a file containing the log message to be verified.

The `ALL` special pattern is not supported for this file, although `DEFAULT` is. If more than one pattern matches, the first match is used.

### 14.3.3.17. The writers file

If this file exists, users listed in it have read/write access (unless they are also listed in the readers file, in which case they have read-only access).

### 14.3.4. Hacking the Repository

Since the repository is a normal directory, albeit one with special contents, it is possible to cd into the directory and examine its contents and/or make changes to the files and directories there. For each file that has been added there will be a file with the same name followed by ,v in a corresponding directory in the repository. These are RCS (the format, not the program) files that contain multiple versions of the file.

> #### NOTE

> Since the activities discussed in this section involve making changes directly to the repository instead of working through CVS commands, you should exercise extreme caution and have current backups when following these instructions.

### 14.3.4.1. Restructuring a project

Restructuring the project by moving files and directories around (and possibly renaming them) in the repository will allow the files to retain their history. The standard way to rename a file when using CVS is to rename the file in the sandbox and do a cvs remove on the old name and a cvs add on the new name. This results in the file being disconnected from its history under the new name, so sometimes it is better to do the renaming directly in the repository, although doing this while people have active sandboxes is dangerous, since the sandboxes will contain information about a file that is no longer in the repository.

### 14.3.4.2. Bulk importing

When importing an entire project, all of the project's files will be added to the repository. But, if some of these files shouldn't have been added, you'll want to remove them. Doing a cvs remove will accomplish this, but copies of those files will remain in the repository's .Attic directory forever. To avoid this, you can delete the files from the repository directly before checking out sandboxes from it.

### 14.3.5. Importing

If you have an existing code base, you'll want to import it into CVS in a way that preserves the most historical information. This section provides instructions for importing projects into CVS from code snapshots or other version control systems. All of these, except the code snapshot import procedure, are based upon conversion to RCS files, followed by placing the RCS files in the proper location in the CVS repository.

### 14.3.5.1. Importing code snapshots

If you have maintained project history archives manually by taking periodic snapshots of the code, you can import the first snapshot, tag it with the date or version number, and then successively overlay the updated files from later archives. Each set can then be committed and tagged in order to bootstrap a repository that maintains the prior history.

For example, first unpack the distributions (this assumes they unpack to directories containing the version numbers):

>     user@localhost$ tar xvzf foo-1.0.tar.gz
>     user@localhost$ tar xvzf foo-1.1.tar.gz
>     user@localhost$ tar xvzf foo-2.0.tar.gz

Next, make a copy of the first version, import it into the CVS repository, check it out to make a sandbox (since importing doesn't convert the source directory into a sandbox), and use cvs tag to give it a symbolic name reflecting the project version:

>     user@localhost$ mkdir foo
>     user@localhost$ cp -R -p foo-1.0/* foo
>     user@localhost$ cd foo
>     user@localhost$ cvs import -m 'Imported version 1.0' foo vendor start
>     user@localhost$ cd ..
>     user@localhost$ mv foo foo.bak
>     user@localhost$ cvs checkout foo
>     user@localhost$ cd foo
>     user@localhost$ cvs tag foo-1_0
>     user@localhost$ cd ..

Now, apply the differences between version 1.0 and 1.1 to the sandbox, commit the changes, and create a tag:

>     user@localhost$ diff -Naur foo-1.0 foo-1.1 | (cd foo; patch -Np1)
>     user@localhost$ cd foo
>     user@localhost$ cvs commit -m 'Imported version 1.1'
>     user@localhost$ cvs tag foo-1_1
>     user@localhost$ cd ..

Now, apply the differences between version 1.1 and 2.0 to the sandbox, commit the changes, and create a tag:

>     user@localhost$ diff -Naur foo-1.1 foo-2.0 | (cd foo; patch -Np1)
>     user@localhost$ cd foo
>     user@localhost$ cvs commit -m 'Imported version 2.0'
>     user@localhost$ cvs tag foo-2_0

Now, you can use the log command to view the history of the files, browse past versions of the files, and continue development under version control.

### 14.3.5.2. Importing from RCS

If you are migrating from RCS to CVS, following these instructions will result in a usable CVS repository. This procedure involves direct modification of the CVS repository, so it should be undertaken with caution.

Before beginning, make sure none of the files to be imported into CVS are locked by RCS. Then, create a new CVS repository and module (or a new module within an existing repository). Next, create directories in the CVS repository to mirror the project's directory structure. Finally, copy all the version files (,v) from the project (which may be in RCS subdirectories) into the appropriate directories in the repository (without RCS subdirectories).

For example, first move aside the directory under RCS control, create an empty directory to build the new CVS structure, import the directory, and then check it out to make a sandbox:

>     user@localhost$ mv foo foo-rcs
>     user@localhost$ mkdir foo
>     user@localhost$ cd foo
>     user@localhost$ cvs import -m 'New empty project' foo vendor start
>     user@localhost$ cd ..
>     user@localhost$ mv foo foo.bak
>     user@localhost$ cvs checkout foo

Next, make directories and add them to the repository to match the structure in the RCS project:

>     user@localhost$ cd foo
>     user@localhost$ mkdir dir
>     user@localhost$ cvs add dir
>     user@localhost$ cd ..

Now, copy the ,v files from the RCS project into the repository for the CVS project:

>     user@localhost$ cp -p foo-rcs/*,v $CVSROOT/foo
>     user@localhost$ cp -p foo-rcs/dir/*,v $CVSROOT/foo/dir

Finally, issue the cvs update command in the sandbox directory to bring in the latest versions of all the files:

>     user@localhost$ cd foo
>     user@localhost$ cvs upd

### 14.3.5.3. Importing from SCCS

To import from SCCS, use the sccs2rcs script located in the contrib directory of the CVS distribution to convert the files to RCS format, and then follow the preceding RCS procedure. You must have both CVS and SCCS installed for this to work. The script's comments contain additional instructions.

### 14.3.5.4. Importing from PVCS

To import from PVCS, use the pvcs_to_rcs script located in the contrib directory of the CVS distribution to convert the files to RCS format, and then follow the previous RCS procedure. You must have both CVS and PVCS installed for this to work. The script's comments contain additional instructions.

### 14.3.6. Using an Interim Shared Sandbox

Sometimes projects will develop unintended environmental dependencies over time, especially when there is no pressure for the code to be relocatable. A project developed outside version control may even be initially developed in place (at its intended installation location). While these practices are not recommended, they do occur in real-world situations; CVS can be helpful in improving the situation, by encouraging relocatability from the beginning of a project.

The default mode of operation for CVS is multiple independent sandboxes, all coordinated with a central shared repository. Code that runs in this environment is necessarily (at least partially) relocatable. So, using CVS from the beginning of a project helps ensure flexibility.

However, if a project is already well underway, an interim approach can be used. For example, you could convert the development area to a single shared sandbox by importing the code into CVS and checking it back out again:

>     user@localhost$ cd /usr/local/bar
>     user@localhost$ cvs import bar vendor start
>     user@localhost$ cd ..
>     user@localhost$ mv bar bar.bak
>     user@localhost$ cvs checkout bar

Chances are good that this approach is too aggressive and will check in more files than absolutely necessary. You can either go back and hack the repository to remove the files that shouldn't be there or just issue the cvs remove command to delete them as you discover them.

In addition, there will probably be some binary files in the sandbox that were imported as text files. Wherever you see a binary file that needs to remain in the repository, you should issue the command cvs admin -kb file, then make a fresh copy from the project backup. Finally, issue the command cvs commit file to commit the fixed file back to the repository.

Having version control in place before making flexibility enhancements is a good idea, since it makes it easier to find (and possibly reverse) changes that cause trouble.

The repository locator (see Section 14.4.1, "Repository Locators") is specified via the -d option or the `$CVSROOT` environment variable. It is stored in the various sandbox CVS/root files. If you are using the password server (pserver), the user ID of the person checking out the sandbox will be remembered. If more than one person is working with a particular sandbox, they will have to share an account for CVS access.

One way to do this is to have a neutral user account, with a password known by everyone with CVS access. Everyone can then issue the cvs login command with the same user ID and password and have access to the repository. Once you are no longer using a shared sandbox, this workaround won't be necessary. However, during the time you are using a shared sandbox, it is important that the developers type their real user IDs into their log messages, since all the changes will appear to be made by the common user.

### 14.3.7. Global Server Option

The server has one global option: --allow-root=rootdir. This option is used to tell the CVS server to accept and process requests for the specified repository.

### 14.3.8. Administrator Commands

Table 14-8 lists the commands that CVS administrators can use to manage their repositories.

#### Table 14-8. Administrator Commands

Command | Description
--- | ---
admin adm rcs | Perform administrative functions
init | Create a new repository
server | Run in server mode

### 14.3.8.1. admin

>     admin
>       [ -b[rev] ]
>       [ -cstring ]
>       [ -kkflag ]
>       [ -l[rev] ]
>       [ -L ]
>       [ -mrev:msg ]
>       [ -nname[:[rev]] ]
>       [ -Nname[:[rev]] ]
>       [ -orange ]
>       [ -q ]
>       [ -sstate[:rev]
>       [ -t[file] ]
>       [ -t-string ]
>       [ -u[rev] ]
>       [ -U ]
>       [ files ... ]

The admin is used to perform administrative functions. If a cvsadmin user group exists, then only those users in that group will be able to run admin with options other than -k. Additional options that may be used with the admin command are listed in Table 14-9.

#### Table 14-9. admin Options

Option | Description
--- | ---
-b[rev] | Set the default branch.
-c string | Obsolete. Set the comment leader.
-k kflag | Set the default keyword substitution mode.
-l[rev] | Lock the specified revision.
-L | Enable strict locking.
-m rev:msg | Change the revision's log message.
-n name[:[rev]] | Give the branch or revision specified the symbolic name name.
-N name[:[rev]] | The same as -n, except that if name is already in use, it is moved.
-o range | Delete revisions permanently.
-q | Don't print diagnostics.
-s state[:rev] | Change the state of a revision.
-t[file] | Set the descriptive text in the RCS file.
-t-string | Set the descriptive text in the RCS file to string.
-u[rev] | Unlock the specified revision.
-U | Disable strict locking.

If the revision specified for -l is a branch, the latest revision on that branch will be used. If no revision is given, the latest revision on the default branch is used.

If the name given for -n is already in use, an error is generated. You can use -N to move a tag (change the revision associated with the tag); however, you should usually use cvs tag or cvs rtag instead.

The -o option is very dangerous and results in a permanent loss of information from the repository. Use it with extreme caution and only after careful consideration. See Table 14-10 for the various ways to specify ranges. There must not be any branches or locks on the revisions to be removed. Beware of interactions between this command and symbolic names.

If no file is specified to the -t option, CVS reads from standard input until it reaches the end of the file or a period on a line by itself.

The determination of the target revision for the -u option is the same as for -l.

#### Table 14-10. Range Formats

Format | Description
--- | ---
rev1`::`rev2 | Eliminate versions between rev1 and rev2, retaining only enough information to go directly from rev1 to rev2. The two specified versions are retained.
`::`rev | The same as rev1::rev2, except the first revision is the branchpoint revision.
rev`::` | The same as rev1::rev2, except the second revision is the end of the branch, and it is deleted instead of retained.
rev | Delete the specified revision.
rev1`:` rev2 | The same as rev1::rev2, except the two named revisions are deleted as well.
`:`rev | The same as ::rev2, except the named revision is deleted as well.
rev`:` | The same as rev1::, except the named revision is deleted as well.

The options in Table 14-11 are present in CVS for historical reasons and should not be used (using these options may corrupt the repository).

#### Table 14-11. Obsolete admin Options

Option | Description
--- | ---
-a logins | Append the logins to the RCS file's access list.
-A oldfile | Append the access list of oldfile to the access list of the RCS file.
-e[logins] | Erases logins from the RCS file's access list, or erases all if a list is not provided.
-i | Create and initialize a new RCS file. Don't use this option. Instead, use add to add files to a CVS repository.
-I | Run interactively. This option doesn't work with client/server CVS and is likely to be removed in a future version.
-V n | Obsolete. This option was used to specify that the RCS files used by CVS should be made compatible with a specific version of RCS.
-x suffixes | This option used to be described as determining the filename suffix for RCS files, but CVS has always only used ,v as the RCS file suffix.

### 14.3.8.2. init

>     init

Initializes the repository. Use the global -d option to specify the repository's directory if `$CVSROOT` isn't set appropriately.

The newly initialized repository will contain a CVSROOT module, but nothing else. Once the repository is initialized, use other CVS commands to add files to it or to check out the CVSROOT module to make changes to the administrative files.

### 14.3.8.3. pserver

>     pserver

Operate as a server, providing access to the repositories specified before the command with the --allow-root option. This command is used in the inetd.conf file, not on the command line. Another global option frequently used with this command is -T (see Table 14-1).

Copyright © 2001 O'Reilly & Associates. All rights reserved.